package com.yunwushanhe.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yunwushanhe.bean.req.RoleAddReq;
import com.yunwushanhe.bean.req.RolePageReq;
import com.yunwushanhe.bean.req.RoleStatusUpdateReq;
import com.yunwushanhe.bean.req.RoleUpdateReq;
import com.yunwushanhe.bean.ret.ResponseResult;
import com.yunwushanhe.bean.vo.*;
import com.yunwushanhe.entity.RoleMenu;
import com.yunwushanhe.mapper.RoleMapper;
import com.yunwushanhe.entity.Role;
import com.yunwushanhe.service.MenuService;
import com.yunwushanhe.service.RoleMenuService;
import com.yunwushanhe.service.RoleService;
import com.yunwushanhe.util.BeanCopyUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.lang.invoke.LambdaConversionException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 角色信息表(Role)表服务实现类
 *
 * @author 抬头看看天
 * @since 2023-08-17 16:05:08
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    @Resource
    private RoleMapper roleMapper;
    @Resource
    private RoleMenuService roleMenuService;
    @Resource
    private MenuService menuService;

    @Override
    public List<String> selectRoleKeyListByUserId(Long id) {
        // 如果是超级管理员，则返回所有权限
        if(id == 1L){
            List<String> roleKeyList = new ArrayList<>();
            roleKeyList.add("admin");
            return roleKeyList;
        }
        return roleMapper.selectRoleKeyListByUserId(id);
    }

    @Override
    public ResponseResult<PageVO<List<RolePageVO>>> listRolePage(RolePageReq rolePageReq) {
        LambdaQueryWrapper<Role> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(rolePageReq.getRoleName()),Role::getRoleName,rolePageReq.getRoleName());
        queryWrapper.eq(StringUtils.hasText(rolePageReq.getStatus()),Role::getStatus,rolePageReq.getStatus());

        Page<Role> rolePage = new Page<>(rolePageReq.getPageNum(), rolePageReq.getPageSize());
        page(rolePage,queryWrapper);

        List<RolePageVO> rolePageVOS = BeanCopyUtil.copyBeanList(rolePage.getRecords(), RolePageVO.class);
        PageVO<List<RolePageVO>> pageVO = new PageVO<>(rolePageVOS, rolePage.getTotal());

        return ResponseResult.ok(pageVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Object> changeRoleStatus(RoleStatusUpdateReq roleStatusUpdateReq) {
        /*LambdaUpdateWrapper<Role> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Role::getId,roleStatusUpdateReq.getRoleId());
        updateWrapper.set(Role::getStatus,roleStatusUpdateReq.getStatus());
        update(updateWrapper);*/
        HashMap<String, Object> eqMap = new HashMap<>();
        eqMap.put("id",roleStatusUpdateReq.getRoleId());

        ArrayList<String> ignoreFieldList = new ArrayList<>();
        ignoreFieldList.add("roleId");

        UpdateWrapper<Role> roleUpdateWrapper = BeanCopyUtil.ignoreNullUpdateWrapper(eqMap, roleStatusUpdateReq, Role.class, ignoreFieldList);
        update(roleUpdateWrapper);
        return ResponseResult.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Object> addRole(RoleAddReq roleAddReq) {
        Role role = BeanCopyUtil.copyBean(roleAddReq, Role.class);
        save(role);

        Long roleId = role.getId();
        List<RoleMenu> roleMenuList = roleAddReq.getMenuIds().stream()
                .map(menuId -> new RoleMenu(roleId,Long.valueOf(menuId)))
                .collect(Collectors.toList());

        roleMenuService.saveBatch(roleMenuList);
        return ResponseResult.ok();
    }

    @Override
    public ResponseResult<RoleUpdateVO> getRoleById(Long id) {
        Role role = getById(id);
        RoleUpdateVO roleUpdateVO = BeanCopyUtil.copyBean(role, RoleUpdateVO.class);
        return ResponseResult.ok(roleUpdateVO);
    }

    @Override
    public ResponseResult<MenuRoleListVO> getRoleMenuTreeByRoleId(Long id) {
        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleMenu::getRoleId,id);
        List<RoleMenu> roleMenuList = roleMenuService.list(queryWrapper);

        List<String> menuIdList = roleMenuList.stream()
                .map(roleMenu -> roleMenu.getMenuId().toString())
                .collect(Collectors.toList());
        List<MenuTreeVO> menuTreeVOList = menuService.getMenuTree().getData();

        return ResponseResult.ok(new MenuRoleListVO(menuTreeVOList,menuIdList));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Object> updateRoleById(RoleUpdateReq roleUpdateReq) {
        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RoleMenu::getRoleId,roleUpdateReq.getId());
        roleMenuService.remove(queryWrapper);

        List<String> menuIdList = roleUpdateReq.getMenuIds();
        List<RoleMenu> roleMenuList = menuIdList.stream()
                .map(menuId -> new RoleMenu(roleUpdateReq.getId(), Long.valueOf(menuId)))
                .collect(Collectors.toList());
        roleMenuService.saveBatch(roleMenuList);

        HashMap<String, Object> eqMap = new HashMap<>();
        ArrayList<String> ignoredFieldList = new ArrayList<>();
        eqMap.put("id",roleUpdateReq.getId());
        ignoredFieldList.add("menuIds");

        UpdateWrapper<Role> roleUpdateWrapper =
                BeanCopyUtil.ignoreNullUpdateWrapper(eqMap, roleUpdateReq, Role.class, ignoredFieldList);
        update(roleUpdateWrapper);
        return ResponseResult.ok();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseResult<Object> deleteRoleById(String id) {
        String[] arrayId = id.split(",");
        ArrayList<Long> listId = new ArrayList<>();
        for (String s : arrayId) {
            listId.add(Long.valueOf(s));
        }
        removeByIds(listId);

        // 把关系表中的关系一并删除了
        LambdaQueryWrapper<RoleMenu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(RoleMenu::getRoleId,listId);
        roleMenuService.remove(queryWrapper);

        return ResponseResult.ok();
    }

    @Override
    public ResponseResult<List<RoleListVO>> getRoleList() {
        List<Role> roleList = list();
        List<RoleListVO> roleListVOList = BeanCopyUtil.copyBeanList(roleList, RoleListVO.class);
        return ResponseResult.ok(roleListVOList);
    }
}

